-
Notifications
You must be signed in to change notification settings - Fork 399
Add Localization Features package for System.CommandLine #1013
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
!string.IsNullOrEmpty(culture)) | ||
CultureInfo.CurrentCulture = CultureInfo.CurrentUICulture = CultureInfo.GetCultureInfo(culture); | ||
|
||
var execCtx = ExecutionContext.Capture(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're using this as guidance, is there an approach that can work without using ExecutionContext
? It's fairly heavy in terms of performance and a bit magical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonsequitur I improved it slightly in 8587a5c
"profiles": { | ||
"LocalizationPlayground": { | ||
"commandName": "Project", | ||
"commandLineArgs": "[env:DOTNET_SYSTEM_GLOBALIZATION_CULTURE=de-DE] -c 3 .NET" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This env should not be needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be a .net core leveled env to do the same thing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wli3 We were hoping to align to whatever environment variables exist already in the SDK but the only one I could find was for specifying the invariant culture, not for specifying other cultures. https://docs.microsoft.com/en-us/dotnet/core/run-time-config/globalization
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my memory is wrong. https://github.com/dotnet/sdk/blob/b1223209644d900702287faea8e9b71f95ec49f8/src/Cli/dotnet/UILanguageOverride.cs#L38
we had a CLI specific flag. If we need a flag for this library that's fine.
I don't think xlf is generated by Arcade. We need to do that so it can fit into existing localization system. But that's also a headache, we would require the contributor to run a build with arcade (which is disabled in "dev mode") and then checkin the new xlfs. Maybe the "right way" is we could have a bot to run and append a checkin for PRs touching resx files. |
Related: #1125 |
TL;DR
System.CommandLine.Localization
that contains functionality that extendsSystem.CommandLine
with localization features.LocalizedHelpBuilder
type that derives from the defaultHelpBuilder
, but offers localized help output.UseLocalization
extension method onCommandLineBuilder
.Details
The new
System.CommandLine.Localization
package uses theMicrosoft.Extensions.Localization
package to provide localization features. By default the implementation uses the Resource Manager basedIStringLocalizerFactory
which provides localization from embedded resources that are compiled from.resx
files at compile time. ref.: Globalization and Localization in ASP.NET CoreUseLocalization
extension methodNew API
The
UseLocalization
extension method is the main entry point that makes the CommandLine application localization aware. In essence it does two things:IStringLocalizerFactory
to theBindingContext
of the invocation.UseHelpBuilder
to setup the newLocalizedHelpBuilder
that outputs help using the string localizer factory mentioned above.The optional
Type
argument is used to specify from which assembly and resource file the strings are localized. If the Type is not specified, the Type that declares the entry point (i.e. theMain
method) in the entry assembly is used.If the Generic Host integration (
System.CommandLine.Hosting
) is being used and the binding context knows how to resolve anIHost
instance, the extension method attempt to resolve theIStringLocalizerFactory
from the service provider of the Generic Host. This will respect any configuration made in the Host setup with regards to logging and localization options. The reference toIHost
is made via reflection, so thatSystem.CommandLine.Localization
does not need to depend on the Generic Host package.LocalizedHelpBuilder
classNew Type
The
LocalizedHelpBuilder
class derives from theSystem.CommandLine
help builder and uses its base implementation as much as possible. In order to localize the output of the static strings in theDefaultHelpText
class (and some constant literals inHelpBuilder
,System.Command.Localization
also adds aLocalizedHelpBuilder.resx
resource file that together with the XLF files provides localized strings for the Help output.In order to localize the actual help on commands, options and arguments, the Localized Help Builder walks the command or option that it is writing output for and clones all symbols (effectively making localized clones). The Localized Help Builder then replaces the
Description
of each symbol with a localized description.